<template>
  <div class="login-container">
    <!-- 动态背景 -->
    <div class="animated-bg">
      <div class="floating-shapes">
        <div class="shape shape-1" />
        <div class="shape shape-2" />
        <div class="shape shape-3" />
        <div class="shape shape-4" />
        <div class="shape shape-5" />
      </div>
      <div class="particles">
        <div v-for="n in 20" :key="n" class="particle" :style="particleStyle(n)" />
      </div>
    </div>

    <!-- 登录卡片 -->
    <div class="login-card">
      <div class="card-header">
        <div class="logo-circle">
          <img src="https://uni-soul-static.oss-cn-chengdu.aliyuncs.com/unisoul-logo.jpg" alt="学途心绘坊" class="logo-image">
        </div>
        <h1 class="title">学途心绘坊</h1>
        <p class="subtitle">管理系统</p>
      </div>

      <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" status-icon>
        <!-- 用户名输入 -->
        <el-form-item prop="username" :show-message="true">
          <div class="input-group" :class="{ 'focused': focusField === 'username' }">
            <div class="input-icon">
              <svg-icon icon-class="user" />
            </div>
            <el-input
              ref="username"
              v-model="loginForm.username"
              placeholder="请输入用户名"
              class="custom-input"
              @focus.native="focusField = 'username'"
              @blur.native="focusField = ''"
            />
          </div>
        </el-form-item>

        <!-- 密码输入 -->
        <el-form-item prop="password" :show-message="true">
          <div class="input-group" :class="{ 'focused': focusField === 'password' }">
            <div class="input-icon">
              <svg-icon icon-class="password" />
            </div>
            <el-input
              :key="passwordType"
              ref="password"
              v-model="loginForm.password"
              :type="passwordType"
              placeholder="请输入密码"
              class="custom-input"
              @focus.native="focusField = 'password'"
              @blur.native="focusField = ''"
              @keyup.enter.native="handleLogin"
            />
            <div class="password-toggle" @click="showPwd">
              <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
            </div>
          </div>
        </el-form-item>

        <!-- 验证码输入 -->
        <el-form-item prop="code" :show-message="true">
          <div class="input-group" :class="{ 'focused': focusField === 'code' }">
            <div class="input-icon">
              <svg-icon icon-class="form" />
            </div>
            <el-input
              v-model="loginForm.code"
              placeholder="请输入验证码"
              style="width: 60%; display: inline-block"
              @keyup.enter.native="handleLogin"
            />
            <img
              :src="captchaImg"
              alt="验证码"
              style="height: 38px; margin-left: 10px; cursor: pointer; border-radius: 6px; border: 1px solid #eee;"
              @click="getCaptchaImg"
            >
          </div>
        </el-form-item>

        <!-- 登录按钮 -->
        <el-button
          :loading="loading"
          class="login-button"
          @click.native.prevent="handleLogin"
        >
          <span v-if="!loading">登录</span>
          <span v-else>登录中...</span>
        </el-button>
      </el-form>
    </div>
  </div>
</template>

<script>
import { validUsername } from '@/utils/validate'
import { API_BASE_URL } from '@/config/api'

export default {
  name: 'Login',
  data() {
    // 校验规则
    const validateUsername = (rule, value, callback) => {
      if (!validUsername(value)) {
        callback(new Error('请输入正确的用户名'))
      } else {
        callback()
      }
    }
    const validatePassword = (rule, value, callback) => {
      if (!value || value.length < 6) {
        callback(new Error('密码不能少于6位'))
      } else {
        callback()
      }
    }
    const validateCode = (rule, value, callback) => {
      if (!value || value.length < 4) {
        callback(new Error('请输入验证码'))
      } else {
        callback()
      }
    }
    return {
      loginForm: {
        username: '',
        password: '',
        code: ''
      },
      loginRules: {
        username: [{ required: true, trigger: 'blur', validator: validateUsername }],
        password: [{ required: true, trigger: 'blur', validator: validatePassword }],
        code: [{ required: true, trigger: 'blur', validator: validateCode }]
      },
      loading: false,
      passwordType: 'password',
      redirect: undefined,
      focusField: '',
      captchaImg: '', // 验证码图片URL
      captchaKey: '', // 验证码key
      particleParams: Array.from({ length: 20 }, () => ({
        left: Math.random() * 100,
        top: Math.random() * 100,
        size: Math.random() * 4 + 2,
        delay: Math.random() * 3,
        duration: Math.random() * 4 + 3
      }))
    }
  },
  watch: {
    $route: {
      handler(route) {
        this.redirect = route.query && route.query.redirect
      },
      immediate: true
    }
  },
  mounted() {
    this.getCaptchaImg()
  },
  methods: {
    // 密码显示/隐藏
    showPwd() {
      this.passwordType = this.passwordType === 'password' ? '' : 'password'
      this.$nextTick(() => {
        this.$refs.password.focus()
      })
    },
    // 获取验证码图片和key
    async getCaptchaImg() {
      try {
        const response = await fetch(`${API_BASE_URL}/common/getCode`, { method: 'GET' })
        const blob = await response.blob()
        this.captchaImg = URL.createObjectURL(blob)
        this.captchaKey = response.headers.get('key')
      } catch (e) {
        console.error('获取验证码失败:', e)
        this.captchaImg = ''
        this.captchaKey = ''
      }
    },
    // 登录
    async handleLogin() {
      this.$refs.loginForm.validate(async valid => {
        if (!valid) return
        if (!this.captchaKey) {
          this.$message.error('请先获取验证码')
          return
        }
        this.loading = true
        try {
          const params = new URLSearchParams({
            userId: this.loginForm.username,
            password: this.loginForm.password,
            code: this.loginForm.code
          })
          const response = await fetch(`${API_BASE_URL}/common/login?${params.toString()}`, {
            method: 'GET',
            headers: {
              key: this.captchaKey
            }
          })
          const result = await response.json()
          if (result.code === 1) {
            const loginData = result.data || {}
            const token = loginData.token || ''
            const pathPermsList = loginData.pathPermsList || []

            // 正确保存 token
            this.$store.commit('user/SET_TOKEN', token)
            localStorage.setItem('token', token)

            // 保存菜单权限供路由动态加载
            this.$store.commit('user/SET_MENUS', pathPermsList)
            this.$store.commit('user/SET_ROUTES_ADDED', false)

            // 设置用户信息（若无独立接口，先用登录名与默认头像）
            this.$store.commit('user/SET_NAME', this.loginForm.username)
            this.$store.commit('user/SET_AVATAR', 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif')

            this.$message.success('登录成功')

            // 等待Vuex状态更新后统一跳到首页，触发路由守卫注入动态路由
            this.$nextTick(() => {
              this.$router.push({ path: '/' })
            })
          } else {
            this.$message.error(result.msg || '登录失败')
            this.getCaptchaImg()
            this.loginForm.code = ''
          }
        } catch (e) {
          console.error('登录错误:', e)
          this.$message.error('登录请求失败')
          this.getCaptchaImg()
          this.loginForm.code = ''
        } finally {
          this.loading = false
        }
      })
    },
    // 粒子动画样式
    particleStyle(n) {
      const p = this.particleParams[n - 1]
      return {
        left: p.left + '%',
        top: p.top + '%',
        width: p.size + 'px',
        height: p.size + 'px',
        animationDelay: p.delay + 's',
        animationDuration: p.duration + 's',
        background: `rgba(240, 103, 124, ${0.18 + 0.18 * (n % 3)})`
      }
    }
  }
}
</script>

<style lang="scss" scoped>
$primary: #f0677c;
$primary-light: #ff8a9a;
$primary-dark: #e0556b;
$gradient: linear-gradient(135deg, #fff 0%, #ffe0ea 100%);

html, body, #app, .login-container {
  height: 100vh;
  min-height: 100vh;
  margin: 0;
  padding: 0;
  overflow: hidden;
  font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
}

.login-container {
  min-height: 100vh;
  width: 100vw;
  background: $gradient;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}

.animated-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
}

.floating-shapes {
  position: absolute;
  width: 100%;
  height: 100%;
  .shape {
    position: absolute;
    border-radius: 50%;
    background: rgba(240, 103, 124, 0.08);
    animation: float 6s ease-in-out infinite;
    &.shape-1 { width: 80px; height: 80px; top: 20%; left: 10%; animation-delay: 0s; }
    &.shape-2 { width: 120px; height: 120px; top: 60%; right: 15%; animation-delay: 1s; }
    &.shape-3 { width: 60px; height: 60px; bottom: 30%; left: 20%; animation-delay: 2s; }
    &.shape-4 { width: 100px; height: 100px; top: 40%; right: 30%; animation-delay: 3s; }
    &.shape-5 { width: 70px; height: 70px; bottom: 20%; right: 10%; animation-delay: 4s; }
  }
}

.particles {
  position: absolute;
  width: 100%;
  height: 100%;
  .particle {
    position: absolute;
    background: rgba(240, 103, 124, 0.18);
    border-radius: 50%;
    animation: particleFloat linear infinite;
  }
}

@keyframes float {
  0%, 100% { transform: translateY(0px) rotate(0deg); }
  50% { transform: translateY(-20px) rotate(180deg); }
}
@keyframes particleFloat {
  0% { transform: translateY(100vh) scale(0); opacity: 0; }
  10% { opacity: 1; }
  90% { opacity: 0.7; }
  100% { transform: translateY(-100px) scale(1); opacity: 0; }
}

.login-card {
  position: relative;
  z-index: 2;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(24px);
  border-radius: 24px;
  padding: 28px 28px 20px 28px;
  width: 380px;
  max-width: 92vw;
  box-shadow: 0 20px 40px rgba(240, 103, 124, 0.08);
  animation: slideUp 0.8s ease-out;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.card-header {
  text-align: center;
  margin-bottom: 28px;
  .logo-circle {
    width: 90px;
    height: 90px;
    background: transparent;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 16px;
    box-shadow: none;
    overflow: hidden;
    position: relative;
    .svg-icon { font-size: 36px; color: white; }
    .logo-image {
      width: 90px;
      height: 90px;
      border-radius: 50%;
      object-fit: cover;
      animation: logoGentle 6s ease-in-out infinite;
      transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
      background: transparent !important;
      mix-blend-mode: multiply;
      filter: contrast(1.1) brightness(1.05);
      image-rendering: -webkit-optimize-contrast;
      image-rendering: crisp-edges;
      &:hover {
        transform: scale(1.08);
        animation-play-state: paused;
        filter: contrast(1.2) brightness(1.1);
      }
    }
  }
  .title {
    font-size: 32px;
    font-weight: 900;
    color: $primary;
    margin: 0 0 6px;
    font-family: 'Brush Script MT', '华文行楷', 'STKaiti', 'KaiTi', '楷体', 'Microsoft YaHei', 'PingFang SC', cursive;
    letter-spacing: 3px;
    text-transform: none;
  }
  .subtitle {
    font-size: 15px;
    color: #666;
    margin: 0;
    font-weight: 400;
  }
}

.login-form {
  width: 100%;
  .el-form-item {
    margin-bottom: 18px;
    .el-form-item__error {
      margin-top: 2px;
      font-size: 13px;
      color: #f0677c;
      font-weight: bold;
      line-height: 1.2;
      padding-left: 44px;
      font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
      white-space: pre-line;
      word-break: break-all;
    }
  }
  .input-group {
    position: relative;
    background: #f8f9fa;
    border-radius: 16px;
    padding: 0 16px;
    height: 48px;
    display: flex;
    align-items: center;
    transition: all 0.3s ease;
    border: 2px solid transparent;
    &.focused {
      background: white;
      border-color: $primary;
      box-shadow: 0 0 0 4px rgba(240, 103, 124, 0.1);
      transform: translateY(-2px);
    }
    .input-icon {
      color: $primary;
      font-size: 18px;
      margin-right: 10px;
      display: flex;
      align-items: center;
    }
    .custom-input {
      flex: 1;
      .el-input__inner {
        border: none !important;
        background: transparent;
        height: 44px;
        font-size: 15px;
        color: #333;
        padding: 0;
        font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
        &::placeholder { color: #999; }
        &:focus {
          border: none !important;
          box-shadow: 0 0 0 2px #f0677c !important;
        }
      }
    }
    .password-toggle {
      color: $primary;
      font-size: 17px;
      cursor: pointer;
      padding: 7px;
      border-radius: 8px;
      transition: all 0.2s ease;
      &:hover { background: rgba(240, 103, 124, 0.1); }
    }
    .captcha-container {
      margin-left: 10px;
      display: flex;
      align-items: center;
      .captcha-img {
        height: 38px;
        margin-left: 10px;
        cursor: pointer;
        border-radius: 6px;
        border: 1px solid #eee;
        transition: box-shadow 0.2s;
        &:hover {
          box-shadow: 0 2px 8px rgba(240, 103, 124, 0.2);
        }
      }
    }
  }
  .login-button {
    width: 100%;
    height: 44px;
    background: linear-gradient(90deg, $primary 60%, $primary-light 100%);
    border: none;
    border-radius: 16px;
    color: white;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: 1px;
    box-shadow: 0 8px 24px rgba(240, 103, 124, 0.13);
    transition: all 0.3s ease;
    margin-top: 8px;
    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 24px rgba(240, 103, 124, 0.18);
    }
    &:active { transform: translateY(-1px); }
  }
}

@keyframes slideUp {
  from { opacity: 0; transform: translateY(30px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes logoGentle {
  0%, 100% {
    transform: translateY(0px) scale(1) rotate(0deg);
    filter: brightness(1);
  }
  25% {
    transform: translateY(-3px) scale(1.02) rotate(1deg);
    filter: brightness(1.05);
  }
  50% {
    transform: translateY(-5px) scale(1.03) rotate(0deg);
    filter: brightness(1.1);
  }
  75% {
    transform: translateY(-2px) scale(1.01) rotate(-1deg);
    filter: brightness(1.05);
  }
}

@media (max-width: 768px) {
  .login-card {
    padding: 18px 6vw 12px 6vw;
    width: 98vw;
    border-radius: 16px;
  }
  .card-header {
    .title { font-size: 19px; }
    .subtitle { font-size: 13px; }
  }
  .login-form {
    .input-group { height: 40px;
      .custom-input .el-input__inner { height: 36px; font-size: 13px; }
      .captcha-container .captcha-img {
        height: 30px;
        min-width: 40px;
      }
    }
    .login-button { height: 40px; font-size: 15px; }
  }
}
</style>

